package team.seekers.hula.question.questionDevelopBook.book.service;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import team.seekers.hula.question.questionDevelopBook.book.entity.dao.BookDO;
import team.seekers.hula.question.questionDevelopBook.book.entity.dao.BookUserDO;
import team.seekers.hula.question.questionDevelopBook.book.entity.dto.BookQueryDTO;
import team.seekers.hula.question.questionDevelopBook.book.entity.dto.BookUserRecordDTO;
import team.seekers.hula.question.questionDevelopBook.book.entity.dto.BookUserSaveDTO;
import team.seekers.hula.question.questionDevelopBook.book.entity.vo.BookReadingInfoVO;
import team.seekers.hula.question.questionDevelopBook.book.entity.vo.BookReadingListVO;
import team.seekers.hula.question.questionDevelopBook.book.mapper.BookUserMapper;
import team.seekers.hula.common.entity.PageResult;
import team.seekers.hula.user.user.service.UserService;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author hbc
 * @since 2022-11-22
 */
@Service
public class BookUserService extends ServiceImpl<BookUserMapper, BookUserDO> {

    @Resource
    private UserService userService;
    @Resource
    private BookService bookService;

    public String save(BookUserSaveDTO saveDTO) {
        return null;
    }

    public void remove(String id) {

    }

    public void record(BookUserRecordDTO recordDTO) {
        lambdaUpdate().set(
                BookUserDO::getLastLocation,recordDTO.getLastLocation()
        ).eq(BookUserDO::getBookId,recordDTO.getBookId()).eq(BookUserDO::getUserId,recordDTO.getUserId()).update();
    }

    public PageResult<BookReadingListVO> pageBookIdsOrderByTime(BookQueryDTO queryDTO) {
        List<BookUserDO> bookUserDOList = lambdaQuery().select(
                BookUserDO::getBookId,
                BookUserDO::getLastLocation,
                BookUserDO::getProgress,
                BookUserDO::getGmtCreate,
                BookUserDO::getGmtModified
        ).eq(BookUserDO::getUserId, queryDTO.getUserId()).list();

        HashMap<String, BookUserDO> bookIdMapBookUserDO = new HashMap<>();
        for (BookUserDO bookUserDO : bookUserDOList) {
            bookIdMapBookUserDO.put(bookUserDO.getBookId(),bookUserDO);
        }

        // 查询书籍信息
        LambdaQueryChainWrapper<BookDO> query = bookService.lambdaQuery().select();

        query.in(BookDO::getId,bookIdMapBookUserDO.keySet());

        if(StringUtils.isNotBlank(queryDTO.getName()))
            query.likeRight(BookDO::getName,queryDTO.getName());


        Page<BookDO> page = query.page(new Page<>(queryDTO.getPageNow(), queryDTO.getPageSize()));
        List<BookReadingListVO> list = page.getRecords().stream().map(bookDO -> {
            return BookReadingListVO.builder()
                    .id(bookDO.getId())
                    .name(bookDO.getName())
                    .cover(bookDO.getCover())
                    .oss(bookDO.getOss())
                    .progress(bookIdMapBookUserDO.get(bookDO.getId()).getProgress())
                    .lastLocation(bookIdMapBookUserDO.get(bookDO.getId()).getLastLocation())
                    .gmtCreate(bookIdMapBookUserDO.get(bookDO.getId()).getGmtCreate())
                    .gmtModified(bookIdMapBookUserDO.get(bookDO.getId()).getGmtModified()).build();
        }).collect(Collectors.toList());

        return new PageResult<>(page.getPages(),list);
    }

    public List<BookReadingListVO> listAllMyBook(String name, String userId) {
        List<BookUserDO> bookUserDOList = lambdaQuery().select(
                BookUserDO::getBookId,
                BookUserDO::getProgress,
                BookUserDO::getLastLocation,
                BookUserDO::getGmtCreate,
                BookUserDO::getGmtModified
        ).eq(BookUserDO::getUserId, userId).list();

        HashMap<String, BookUserDO> bookIdMapBookUserDO = new HashMap<>();
        for (BookUserDO bookUserDO : bookUserDOList) {
            bookIdMapBookUserDO.put(bookUserDO.getBookId(),bookUserDO);
        }

        // 查询书籍信息
        LambdaQueryChainWrapper<BookDO> query = bookService.lambdaQuery().select();

        query.in(BookDO::getId,bookIdMapBookUserDO.keySet());

        if(StringUtils.isNotBlank(name))
            query.likeRight(BookDO::getName,name);

        List<BookReadingListVO> list = query.list().stream().map(bookDO -> {
            return BookReadingListVO.builder()
                    .id(bookDO.getId())
                    .name(bookDO.getName())
                    .cover(bookDO.getCover())
                    .oss(bookDO.getOss())
                    .progress(bookIdMapBookUserDO.get(bookDO.getId()).getProgress())
                    .lastLocation(bookIdMapBookUserDO.get(bookDO.getId()).getLastLocation())
                    .gmtCreate(bookIdMapBookUserDO.get(bookDO.getId()).getGmtCreate())
                    .gmtModified(bookIdMapBookUserDO.get(bookDO.getId()).getGmtModified()).build();
        }).collect(Collectors.toList());

        return list;
    }

    public BookReadingInfoVO getBookReadingInfoVO(String bookId, String userId) {
        // 查询基本信息
        BookUserDO bookUserDO = lambdaQuery().select(
                BookUserDO::getBookId,
                BookUserDO::getProgress,
                BookUserDO::getLastLocation,
                BookUserDO::getGmtCreate,
                BookUserDO::getGmtModified
        ).eq(BookUserDO::getBookId, bookId).eq(BookUserDO::getUserId, userId).one();

        BookDO bookDO = bookService.getById(bookId);

        return BookReadingInfoVO.builder()
                .id(bookDO.getId())
                .name(bookDO.getName())
                .cover(bookDO.getCover())
                .oss(bookDO.getOss())
                .progress(bookUserDO.getProgress())
                .lastLocation(bookUserDO.getLastLocation())
                .gmtCreate(bookUserDO.getGmtCreate())
                .gmtModified(bookUserDO.getGmtModified()).build();
    }
}
